package config;

import com.sun.nio.file.SensitivityWatchEventModifier;
import eventbus.PageEventBus;
import eventbus.PageEvents;

import java.nio.file.*;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 配置监视器
 * 发现配置文件更改时，即使更新内存并发布配置更新事件
 *
 * @author wyl
 */
public class ConfigWatch {
    private static final String CONFIG_FOLDER = "./res";
    private static final String CONFIG_FILENAME = "config.ini";

    private volatile static boolean inhibition = false;

    public static void startWatch() throws Exception {
        Path path = Paths.get(CONFIG_FOLDER);
        WatchService watch = FileSystems.getDefault().newWatchService();
        path.register(watch, new WatchEvent.Kind[]{StandardWatchEventKinds.ENTRY_MODIFY}, SensitivityWatchEventModifier.LOW);

        ExecutorService service = Executors.newSingleThreadExecutor();
        service.execute(() -> {
            System.out.println("开始进行配置文件的监听");
            try {
                while (true) {
                    WatchKey key = watch.take();
                    List<WatchEvent<?>> watchEventList = key.pollEvents();
                    for (WatchEvent<?> event : watchEventList) {
                        if (event.kind() == StandardWatchEventKinds.OVERFLOW) {
                            continue;
                        }
                        if (event.kind() == StandardWatchEventKinds.ENTRY_MODIFY) {
                            // 返回触发事件的文件或目录的路径（相对路径）
                            Path fileName = (Path) event.context();
                            if (fileName.toString().equals(CONFIG_FILENAME) && !inhibition) {
                                PageEventBus.publish(PageEvents.CONFIG_CHANGED_EVENT);
                                System.out.println("配置文件更新,配置类进行reload");
                                AppConfig.reload();
                            }
                        }
                    }
                    if (!key.reset()) {
                        break;
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            service.shutdown();
        });
    }

    //抑制监听器自动进行配置重新载入，由于自己通过程序更改也会被检测到
    public static void setInhibition() {
        inhibition = true;
    }

    //解除抑制
    public static void disinhibition() {
        inhibition = false;
    }

}
